import os
import logging
import requests
from pathlib import Path
from code.external.kelin_service import KelinAIService
from code.external.oss_utils import OssManager

class StyleProcessor:
    def __init__(self, api_key=None, oss_manager=None):
        """
        初始化风格处理器
        :param api_key: 可灵AI API密钥，如果为None则从环境变量获取
        :param oss_manager: OSS管理器实例，如果为None则创建新实例
        """
        # 初始化可灵AI服务
        self.kelin_service = KelinAIService(api_key=api_key)
        
        # 初始化OSS管理器
        self.oss_manager = oss_manager or OssManager()
        
        # 检查服务可用性
        self.available = self.kelin_service.available and self.oss_manager.available
        if not self.available:
            if not self.kelin_service.available:
                logging.warning("可灵AI服务初始化失败，图像风格转换功能将不可用")
            if not self.oss_manager.available:
                logging.warning("OSS管理器初始化失败，图像上传功能将不可用")
    
    def process_image(self, image_path, prompt, negative_prompt=None, output_dir=None, output_filename=None):
        """
        处理图像并应用风格转换
        :param image_path: 输入图像路径
        :param prompt: 风格描述提示词
        :param negative_prompt: 负向提示词
        :param output_dir: 输出目录，如果为None则使用输入图像所在目录
        :param output_filename: 输出文件名，如果为None则自动生成
        :return: 成功时返回本地保存的图像路径，失败时返回None
        """
        if not self.available:
            logging.warning("风格处理器未正确初始化，无法处理图像")
            return None
            
        try:
            # 检查图像文件是否存在
            image_path = Path(image_path)
            if not image_path.exists():
                logging.error(f"图像文件不存在: {image_path}")
                return None
            
            # 设置输出目录
            if output_dir is None:
                output_dir = image_path.parent
            else:
                output_dir = Path(output_dir)
                os.makedirs(output_dir, exist_ok=True)
            
            # 设置输出文件名
            if output_filename is None:
                output_filename = f"{image_path.name}"
            
            output_path = output_dir / output_filename
            
            logging.info(f"开始处理图像: {image_path}")
            logging.info(f"使用提示词: {prompt}")
            if negative_prompt:
                logging.info(f"使用负向提示词: {negative_prompt}")
            
            # 执行图像风格转换
            result_url = self.kelin_service.image_style_transfer(
                image_path=str(image_path),
                prompt=prompt,
                negative_prompt=negative_prompt
            )
            
            if not result_url:
                logging.error("图像风格转换失败")
                return None
            
            logging.info(f"图像风格转换成功，结果URL: {result_url}")
            
            # 下载转换后的图像
            logging.info(f"正在下载转换后的图像到: {output_path}")
            response = requests.get(result_url)
            if response.status_code == 200:
                with open(output_path, "wb") as f:
                    f.write(response.content)
                logging.info(f"图像下载成功: {output_path}")
                return str(output_path)
            else:
                logging.error(f"下载图像失败，状态码: {response.status_code}")
                return None
        except Exception as e:
            logging.error(f"处理图像时发生错误: {str(e)}")
            return None
    
    def process_batch(self, image_paths, prompt, negative_prompt=None, output_dir=None):
        """
        批量处理图像并应用风格转换
        :param image_paths: 输入图像路径列表
        :param prompt: 风格描述提示词
        :param negative_prompt: 负向提示词
        :param output_dir: 输出目录，如果为None则使用各输入图像所在目录
        :return: 成功处理的图像路径列表
        """
        if not self.available:
            logging.warning("风格处理器未正确初始化，无法批量处理图像")
            return []
            
        successful_paths = []
        for image_path in image_paths:
            result_path = self.process_image(
                image_path=image_path,
                prompt=prompt,
                negative_prompt=negative_prompt,
                output_dir=output_dir
            )
            if result_path:
                successful_paths.append(result_path)
        
        logging.info(f"批量处理完成，成功处理{len(successful_paths)}/{len(image_paths)}个图像")
        return successful_paths
    
    def process_and_upload(self, image_path, prompt, negative_prompt=None, output_dir=None, oss_path=None):
        """
        处理图像并上传到OSS
        :param image_path: 输入图像路径
        :param prompt: 风格描述提示词
        :param negative_prompt: 负向提示词
        :param output_dir: 输出目录，如果为None则使用输入图像所在目录
        :param oss_path: OSS存储路径，如果为None则自动生成
        :return: 成功时返回OSS URL，失败时返回None
        """
        if not self.available:
            logging.warning("风格处理器未正确初始化，无法处理并上传图像")
            return None
            
        try:
            # 处理图像
            local_path = self.process_image(
                image_path=image_path,
                prompt=prompt,
                negative_prompt=negative_prompt,
                output_dir=output_dir
            )
            
            if not local_path:
                logging.error("图像处理失败，无法上传")
                return None
            
            # 上传到OSS
            logging.info(f"正在上传处理后的图像到OSS: {local_path}")
            oss_url = self.oss_manager.upload_file(local_path, oss_path)
            
            if oss_url:
                logging.info(f"图像上传成功，OSS URL: {oss_url}")
                return oss_url
            else:
                logging.error("图像上传失败")
                return None
        except Exception as e:
            logging.error(f"处理并上传图像时发生错误: {str(e)}")
            return None